package com.zn.socketReceiver;
import com.zn.asycn.CalculateKLineExecutor;
import com.zn.web.rpc.MdRemoteCall;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.IOException;
import java.net.Socket;

/**
 * Created by yinjiawei on 2018/7/12.
 */
public class SocketHandler implements SocketStatusListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(SocketHandler.class);
    private static SocketHandler socketHandler;
    public Socket socket=null;
    private ReaderTask reader;


    public SocketHandler(String host, int port,RedisTemplate<String,String> redisTemplate,
                         MongoTemplate mongoTemplate,MdRemoteCall mdRemoteCall,CalculateKLineExecutor calculateKLineExecutor) throws IOException{
        this.socket = new Socket(host, port);
        this.socket.setTcpNoDelay(true);
        this.socket.setKeepAlive(true);
        this.socket.setTcpNoDelay(true);
        this.reader = new ReaderTask(socket,redisTemplate,mongoTemplate,mdRemoteCall,calculateKLineExecutor);
        listen(true);
        onSocketStatusChanged(socket, STATUS_OPEN, null);
    }

    public static SocketHandler getInstance(String host,int port,RedisTemplate<String,String> redisTemplate,
                                            MongoTemplate mongoTemplate,CalculateKLineExecutor calculateKLineExecutor,MdRemoteCall mdRemoteCall) throws IOException{
        if (socketHandler == null) {
            synchronized (SocketHandler.class) {
                if (socketHandler == null) {
                    LOGGER.warn("host:" + host + ",port:" + port);
                    socketHandler = new SocketHandler(host,port,redisTemplate,mongoTemplate,mdRemoteCall,calculateKLineExecutor);
                }
            }
        }
        return socketHandler;
    }

    public static void setEmpty(){
        socketHandler=null;
    }

    /**
     * 判断是否断开连接，断开返回true,没有返回false
     * @return
     */
    public Boolean isServerClose(){
        try{
            this.socket.sendUrgentData(0xFF);//发送1个字节的紧急数据，默认情况下，服务器端没有开启紧急数据处理，不影响正常通信
            return false;
        }catch(Exception se){
            return true;
        }
    }


    public void listen(boolean isListen)
    {
        this.reader.startListener(this);

    }

    public void shutDown() {

        if(!socket.isClosed() && socket.isConnected())
        {
            try {
                reader.finish();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
                onSocketStatusChanged(socket, STATUS_CLOSE, e);
            }finally{
                reader = null;
                LOGGER.info("Socket连接已关闭！！");
            }
        }
    }

    @Override
    public void onSocketStatusChanged(Socket socket,int status, Exception e) {
        switch (status) {
            case SocketStatusListener.STATUS_CLOSE:
            case SocketStatusListener.STATUS_RESET:
            case SocketStatusListener.STATUS_PIP_BROKEN:
                shutDown();
                break;
            default:
                break;
        }
    }


}
